package com.unibuy.smartdevice;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.unibuy.smartdevice.exception.ErrorCode;
import com.unibuy.smartdevice.exception.Logs;

import java.util.Timer;
import java.util.TimerTask;

public abstract class HandlerAbstract implements Runnable{
    private Logs logs;
    private String srcClassName;
    private Context context;
    private int code;
    private String message;
    private Handler handler;

    public String getSrcClassName() {
        return srcClassName;
    }

    public Logs getLogs() {
        return logs;
    }

    public Context getContext() {
        return context;
    }

    public Handler getHandler() {
        return handler;
    }

    public HandlerAbstract(Context context, Logs logs) {
        this.logs = logs;
        this.context = context;
        this.handler = new InnerHandler(Looper.getMainLooper());
    }

    private class InnerHandler extends Handler {
        public InnerHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            Bundle bundle = msg.getData();
            String srcClassName = bundle.getString("srcClassName", "");
            int code = bundle.getInt("code", 0);
            String message = bundle.getString("message", "");

            getLogs().info("handleMessage:srcClassName:" + srcClassName + " code:" + code + " msg:" + message);
            execute(context, code, message);
        }
    }

    @Override
    public void run() {
        getLogs().info("run:srcClassName:" + getSrcClassName() + " code:" + code + " msg:" + message);
        execute(this.context, this.code, this.message);
    }

    private void perform() {
        getLogs().info("perform:srcClassName:" + getSrcClassName() + " code:" + code + " msg:" + message);
        handler.post(this);
    }

    private void perform(int delayedMillis) {
        getLogs().info("perform("+delayedMillis+"):srcClassName:" + getSrcClassName() + " code:" + code + " msg:" + message);
        handler.postDelayed(this, delayedMillis);
    }

    private void neglect() {
        getLogs().info("neglect:srcClassName:" + getSrcClassName() + " code:" + code + " msg:" + message);
        handler.removeCallbacks(this);
    }

    public void send(String srcClassName, int code, String message, int delayedMillis) {
        getLogs().info("send("+delayedMillis+"):srcClassName:" + srcClassName + " code:" + code + " msg:" + message);

        Message msg = Message.obtain();
        Bundle bundle = new Bundle();
        bundle.putString("srcClassName", srcClassName);
        bundle.putInt("code", code);
        bundle.putString("message", message);
        msg.setData(bundle);

        if (delayedMillis > 0) {
            handler.sendMessageDelayed(msg, delayedMillis);
        } else {
            handler.sendMessage(msg);
        }
    }

    public void send(String srcClassName, int code, String message) {
        send(srcClassName, code, message,0);
    }

    public void send(String srcClassName, String message, int delayedMillis) {
        send(srcClassName, 0, message, delayedMillis);
    }

    public void send(String srcClassName, String message) {
        send(srcClassName, 0, message);
    }

    public void start(String srcClassName, int code, String message) {
        this.srcClassName = srcClassName;
        this.code = code;
        this.message = message;
        perform();
    }

    public void start(String srcClassName, int code, String message, int delayedMillis) {
        this.srcClassName = srcClassName;
        this.code = code;
        this.message = message;
        perform(delayedMillis);
    }

    public void start(String srcClassName, String message) {
        start(srcClassName,0, message);
    }

    public void start(String srcClassName, String message, int delayedMillis) {
        start(srcClassName,0, message, delayedMillis);
    }

    protected abstract void execute(Context context, int code, String message);
}
